package com.yuyaogc.lowcode.engine.loader;

import com.yuyaogc.lowcode.engine.container.Container;
import com.yuyaogc.lowcode.engine.entity.Module;
import com.yuyaogc.lowcode.engine.plugin.IPlugin;
import com.yuyaogc.lowcode.engine.plugin.Plugins;
import com.yuyaogc.lowcode.engine.util.ClassUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.*;

public abstract class Loader {
    public static Logger logger = LoggerFactory.getLogger(Loader.class);

    private static Loader loader;

    public static Loader getLoader() {
        return loader;
    }

    public static void setLoader(Loader loader1) {
        loader = loader1;
    }


    /**
     * 加载插件
     * @param plugins
     */
    public void loadPlugin(Plugins plugins) {
        List<IPlugin> pluginList = plugins.getPluginList();
        if (pluginList == null) {
            return;
        }

        for (IPlugin plugin : plugins.getPluginList()) {
            try {
                if (plugin.start() == false) {
                    String message = "Plugin start error: " + plugin.getClass().getName();
                    throw new RuntimeException(message);
                }
            } catch (Exception e) {
                String message = "Plugin start error: " + plugin.getClass().getName() + ". \n" + e.getMessage();
                throw new RuntimeException(message, e);
            }

        }
    }


    /**
     * 加载模组
     * @param jarUrlList
     * @throws IOException
     */
    public void load_modules(List<String> jarUrlList) throws IOException {
        List<Module> moduleList = new ArrayList<>();
        ClassUtils.buildModule(jarUrlList, moduleList);
        moduleList.forEach(Module::build_model_class);
        Container.me().buildInherit();
        moduleList.forEach(Module::init_models);
        moduleList.forEach(Module::load_data);
        this._register_hook(moduleList);
    }


    /**
     * 注册钩子
     * @param applicationList
     */
    public void _register_hook(List<Module> applicationList){
        for(Module application: applicationList){
            application._register_hook();
        }
    }

    public abstract void setUp();

    public abstract void shutdown();
}
